from django.shortcuts import render
from bid.models import AssetInfo
from rest_framework import viewsets
from rest_framework.request import Request
from rest_framework import status
from loguru import logger
from op_drf.pagination import Pagination
from op_drf.response import SuccessResponse
from op_drf.viewsets import CustomModelViewSet
from op_drf.dj_utils import set_delete
from op_drf.filters import DataLevelPermissionsFilter
from .serializers import ReadAssetInfoSerializer, ExportAssetSerializer, \
    UpdateAssetInfoSerializer, CreateAssetInfoSerializer
from bid.filters import AssetInfoFilter

# 附件导出功能
from op_drf.export_excel import export_excel_save_model, excel_to_data
from op_drf.request_util import get_verbose_name


class AssetInfoViewSet(CustomModelViewSet):
    # 数据
    queryset = AssetInfo.objects.all()
    if hasattr(AssetInfo,"is_delete"):
        queryset = queryset.filter(is_delete=False)

    # 显示序列化
    serializer_class = ReadAssetInfoSerializer
    # 创建序列化
    create_serializer_class = CreateAssetInfoSerializer
    # 更新序列化
    update_serializer_class = UpdateAssetInfoSerializer
    # 分页
    pagination_class = Pagination
    # 筛选
    filter_class = AssetInfoFilter
    # 权限，根据用户设置访问权限
    extra_filter_backends = [DataLevelPermissionsFilter]

    # update_extra_permission_classes = (CommonPermission,)
    # destroy_extra_permission_classes = (CommonPermission,)
    # create_extra_permission_classes = (CommonPermission,)
    # 搜索字段
    search_fields = ("asset_code",)
    # 默认排序
    ordering = ["-create_time"]

    # 导入
    import_field_data = {
        "asset_code": "资产编号",
        "asset_name": "资产名称",
    }
    import_serializer_class = create_serializer_class

    # 导出字段
    export_field_data = [
        "资产编号",
        "资产名称",
        "添加时间",
    ]
    # 导出序列化类
    export_serializer_class = ExportAssetSerializer

    def destroy(self, request: Request, *args, **kwargs):
        logger.debug("前端传入的数据： %s" % request.data)
        logger.debug("前端携带的数据： %s" % kwargs)

        instance = self.get_object_list()
        # instance = self.get_object()
        logger.debug(instance)
        if hasattr(self, "handle_logging"):
            self.handle_logging(request, instance=instance, *args, **kwargs)
        self.perform_destroy(instance)
        return SuccessResponse(status=status.HTTP_204_NO_CONTENT)

    def perform_destroy(self, instance):
        # instance.delete()
        # 不再执行物理删除，执行逻辑删除
        set_delete(instance)

    def importTemplate(self, request: Request, *args, **kwargs):
        """
        导入功能
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        assert self.import_field_data, "'%s' 请配置对应的导出模板字段。" % self.__class__.__name__
        # 导出模板
        if request.method == "GET":
            # 示例数据
            queryset = self.filter_queryset(self.get_queryset())
            return SuccessResponse(
                export_excel_save_model(
                    request,
                    self.import_field_data.values(),
                    [],
                    f"导入{get_verbose_name(queryset)}模板.xls",
                )
            )
        updateSupport = request.data.get("updateSupport")
        # 从excel中组织对应的数据结构，然后使用序列化器保存
        data = excel_to_data(request.data.get("file_url"), self.import_field_data)
        queryset = self.filter_queryset(self.get_queryset())
        unique_list = [
            ele.attname for ele in queryset.model._meta.get_fields() if hasattr(ele, "unique") and ele.unique == True
        ]
        for ele in data:
            # 获取 unique 字段
            filter_dic = {i: ele.get(i) for i in list(set(self.import_field_data.keys()) & set(unique_list))}
            instance = filter_dic and queryset.filter(**filter_dic).first()
            if instance and not updateSupport:
                continue
            if not filter_dic:
                instance = None

            serializer = self.import_serializer_class(instance, data=ele)
            serializer.is_valid(raise_exception=True)
            serializer.save()

        return SuccessResponse(msg=f"导入成功！")

    # 批量创建，通过serializer验证
    def create(self, request: Request, *args, **kwargs):
        logger.debug("前端传入的数据： %s" % request.data)
        logger.debug("请求携带的数据： %s" % kwargs)

        asset_num = request.data.pop("asset_num", 0)

        assert type(asset_num) in [int] and asset_num > 0,f"参数错误，未输入数量!"
        # 批量通过serializers创建
        create_data = []
        for i in range(asset_num):
            create_data.append(request.data)

        serializer = self.get_serializer(data=create_data, many=True)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        if hasattr(self, "handle_logging"):
            self.handle_logging(request, instance=serializer.instance, *args, **kwargs)
        headers = self.get_success_headers(serializer.data)
        logger.debug("序列化后的数据： %s" % serializer.data)
        return SuccessResponse(serializer.data, status=status.HTTP_201_CREATED, headers=headers)


    def export(self, request: Request, *args, **kwargs):
        """
        导出功能
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        assert self.export_field_data, "'%s' 请配置对应的导出模板字段。" % self.__class__.__name__
        queryset = self.filter_queryset(self.get_queryset()).order_by("asset_code")
        data = self.export_serializer_class(queryset, many=True).data
        return SuccessResponse(
            export_excel_save_model(
                request,
                self.export_field_data,
                data,
                f"导出{get_verbose_name(queryset)}.xls",
            )
        )
